﻿using System;
using System.Diagnostics;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text.RegularExpressions;
using System.Threading;
using chromium.Cert;
using chromium.GAE;
using chromium.Log;
using chromium.Utils;
using HttpListener = chromium.Proxy.HttpListener;

namespace chromium
{
    internal class Program
    {
        private static readonly Regex GoogleHostRegex = new Regex("CN=[^\\.]+\\.google\\.(com|cn)", RegexOptions.IgnoreCase | RegexOptions.Compiled);

        private static void Main(string[] args)
        {
            SSPICertUtils.NormalizeHost("www.google.com");

            LogManager.SetLogger(new ConsoleLogger());

            ServicePointManager.DefaultConnectionLimit = 16;
            ServicePointManager.Expect100Continue = false;
            ServicePointManager.ServerCertificateValidationCallback += TrustAll;
            ServicePointManager.CheckCertificateRevocationList = true;

            Process spdyProcess = null;
            if (Settings.Spdy)
            {
                ProcessStartInfo ps = new ProcessStartInfo("java") { Arguments = "-jar -Xbootclasspath/p:npn.jar spdy.jar " + Settings.SpdyPort, CreateNoWindow = false, UseShellExecute = false };
                spdyProcess = Process.Start(ps);
                Thread.Sleep(1000);
            }

            DnsHelper.Start();

            var listener = new HttpListener(Settings.Port);

            listener.Start();

            Console.WriteLine("Proxy Started at port: " + Settings.Port);

            Console.Read();

            if (spdyProcess != null)
                spdyProcess.Kill();

            Console.WriteLine("Exit");

        }

        private static bool TrustAll(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslpolicyerrors)
        {
            if (sslpolicyerrors == SslPolicyErrors.None)
                return true;
            if (sslpolicyerrors == SslPolicyErrors.RemoteCertificateNameMismatch)
            {
                return GoogleHostRegex.IsMatch(certificate.Subject);
            }

            LogManager.GetLogger("Cert").DebugFormat("Cert rejected.{0},{1}", certificate.Subject, certificate.Issuer);
            return false;
        }
    }
}